#ifndef GPXPARSER
#define GPXPARSER

#include <io\osmio.h>

class gpx_generator {

    llcoordinates base_resolution;                  ///< features of generated trajectory

    coordinates2d min;                              ///< gpx file 2d bounding box
    coordinates2d max;                              ///< gpx file 2d bounding box

    coordinates2d delta;                            ///< get size of the bounding box
    coordinates2d scene_size;                       ///< size of the scene

    std::vector<track<coordinates2i> > base_tracks; ///< loaded and transformed gpx tracks at basic Resolution

    std::vector<track<coordinates2i> > gen_tracks;            ///< generated gpx tracks at requested resolution
    std::vector<track<coordinates2i> >::iterator tracks_iter; ///< tracks iterator

  private:

    /**
     * Function transform input coordinate c to resolution 
     * \param c transformed coordinate xy
     * \param resolution resolution to which coordinate c has to be transformed
     */
    coordinates2i transform(coordinates2i c, llcoordinates resolution);

  public:

    /**
     * Function set the generator parameters
     * \param osm instance of osmfile containing gpx tracks from parsed gpx file
     * \param base_resolution basic resolution of generated tracks
     */
    void initialize(osmfile *osm, llcoordinates base_resolution);

    /**
     * Function return actual track and move to next
     * \return instance of generated trajectory
     */
    trajectory *next();

    /**
     * Function set the tracks iterator to first track
     */
    void start() {
      tracks_iter = gen_tracks.begin();
    };

    /**
     * Function return number of tracks
     */
    int size() {
      return (int) gen_tracks.size();
    };

    /**
     * Function return average length of generated tracks
     */
    int avgLength() {
      int avgsize = 0;

      for (int i = 0; i != gen_tracks.size(); i++) {
        avgsize += gen_tracks[i].size();
      }
      return avgsize / gen_tracks.size();
    };

    /**
     * Function return min length from generated tracks
     */
    int minLength() {
      int minlen = gen_tracks[0].size();

      for (int i = 0; i != gen_tracks.size(); i++) {
        if (gen_tracks[i].size() < minlen) minlen = gen_tracks[i].size();
      }
      return minlen;
    };

    /**
     * Function return max length from generated tracks
     */
    int maxLength() {
      int maxlen = 0;

      for (int i = 0; i != gen_tracks.size(); i++) {
        if (gen_tracks[i].size() > maxlen) maxlen = gen_tracks[i].size();
      }
      return maxlen;
    };

    /**
     * Operator [] return track at index
     * \param index index of the requested track
     * \return requested track at index
     */
    track<coordinates2i> operator[](int index) {
      return gen_tracks[index];
    }

    /**
     * Function start tracks generation from input trajectories
     * \param resolution resolution of generated tracks
     */
    void generate(llcoordinates resolution);

    /**
     * Function return resolution of the scene
     * \return resolution of the tracks in xy
     */
    coordinates2i getResolution();

    /**
     * Function return true if we have readed all tracks using next()
     * \return true if we have readed all tracks otherwise return false
     */
    bool end();

    /**
     * Constructor
     */
    gpx_generator();

    /**
     * Desructor
     */
    ~gpx_generator();
  };

  #endif